home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / fax / src / libtiff / tif_open.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  9KB  |  382 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Header: /usr/people/sam/tiff/libtiff/RCS/tif_open.c,v 1.39 92/10/21 14:16:48 sam Rel $";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler
  7.  * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
  8.  *
  9.  * Permission to use, copy, modify, distribute, and sell this software and 
  10.  * its documentation for any purpose is hereby granted without fee, provided
  11.  * that (i) the above copyright notices and this permission notice appear in
  12.  * all copies of the software and related documentation, and (ii) the names of
  13.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  14.  * publicity relating to the software without the specific, prior written
  15.  * permission of Sam Leffler and Silicon Graphics.
  16.  * 
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  18.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  19.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  20.  * 
  21.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  22.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  23.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  24.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  25.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  26.  * OF THIS SOFTWARE.
  27.  */
  28.  
  29. /*
  30.  * TIFF Library.
  31.  */
  32. #include "tiffiop.h"
  33.  
  34. static const long typemask[13] = {
  35.     0L,        /* TIFF_NOTYPE */
  36.     0x000000ffL,    /* TIFF_BYTE */
  37.     0xffffffffL,    /* TIFF_ASCII */
  38.     0x0000ffffL,    /* TIFF_SHORT */
  39.     0xffffffffL,    /* TIFF_LONG */
  40.     0xffffffffL,    /* TIFF_RATIONAL */
  41.     0x000000ffL,    /* TIFF_SBYTE */
  42.     0x000000ffL,    /* TIFF_UNDEFINED */
  43.     0x0000ffffL,    /* TIFF_SSHORT */
  44.     0xffffffffL,    /* TIFF_SLONG */
  45.     0xffffffffL,    /* TIFF_SRATIONAL */
  46.     0xffffffffL,    /* TIFF_FLOAT */
  47.     0xffffffffL,    /* TIFF_DOUBLE */
  48. };
  49. static const int bigTypeshift[13] = {
  50.     0,        /* TIFF_NOTYPE */
  51.     24,        /* TIFF_BYTE */
  52.     0,        /* TIFF_ASCII */
  53.     16,        /* TIFF_SHORT */
  54.     0,        /* TIFF_LONG */
  55.     0,        /* TIFF_RATIONAL */
  56.     16,        /* TIFF_SBYTE */
  57.     16,        /* TIFF_UNDEFINED */
  58.     24,        /* TIFF_SSHORT */
  59.     0,        /* TIFF_SLONG */
  60.     0,        /* TIFF_SRATIONAL */
  61.     0,        /* TIFF_FLOAT */
  62.     0,        /* TIFF_DOUBLE */
  63. };
  64. static const int litTypeshift[13] = {
  65.     0,        /* TIFF_NOTYPE */
  66.     0,        /* TIFF_BYTE */
  67.     0,        /* TIFF_ASCII */
  68.     0,        /* TIFF_SHORT */
  69.     0,        /* TIFF_LONG */
  70.     0,        /* TIFF_RATIONAL */
  71.     0,        /* TIFF_SBYTE */
  72.     0,        /* TIFF_UNDEFINED */
  73.     0,        /* TIFF_SSHORT */
  74.     0,        /* TIFF_SLONG */
  75.     0,        /* TIFF_SRATIONAL */
  76.     0,        /* TIFF_FLOAT */
  77.     0,        /* TIFF_DOUBLE */
  78. };
  79.  
  80. /*
  81.  * Initialize the bit fill order, the
  82.  * shift & mask tables, and the byte
  83.  * swapping state according to the file
  84.  * contents and the machine architecture.
  85.  */
  86. static
  87. DECLARE3(TIFFInitOrder, register TIFF*, tif, int, magic, int, bigendian)
  88. {
  89.     /* XXX how can we deduce this dynamically? */
  90.     tif->tif_fillorder = FILLORDER_MSB2LSB;
  91.  
  92.     tif->tif_typemask = typemask;
  93.     if (magic == TIFF_BIGENDIAN) {
  94.         tif->tif_typeshift = bigTypeshift;
  95.         if (!bigendian)
  96.             tif->tif_flags |= TIFF_SWAB;
  97.     } else {
  98.         tif->tif_typeshift = litTypeshift;
  99.         if (bigendian)
  100.             tif->tif_flags |= TIFF_SWAB;
  101.     }
  102. }
  103.  
  104. int
  105. DECLARE2(_TIFFgetMode, const char*, mode, const char*, module)
  106. {
  107.     int m = -1;
  108.  
  109.     switch (mode[0]) {
  110.     case 'r':
  111.         m = O_RDONLY;
  112.         if (mode[1] == '+')
  113.             m = O_RDWR;
  114.         break;
  115.     case 'w':
  116.     case 'a':
  117.         m = O_RDWR|O_CREAT;
  118.         if (mode[0] == 'w')
  119.             m |= O_TRUNC;
  120.         break;
  121.     default:
  122.         TIFFError(module, "\"%s\": Bad mode", mode);
  123.         break;
  124.     }
  125.     return (m);
  126. }
  127.  
  128. TIFF*
  129. #if USE_PROTOTYPES
  130. TIFFClientOpen(
  131.     const char* name, const char* mode,
  132.     void* clientdata,
  133.     TIFFReadWriteProc readproc,
  134.     TIFFReadWriteProc writeproc,
  135.     TIFFSeekProc seekproc,
  136.     TIFFCloseProc closeproc,
  137.     TIFFSizeProc sizeproc,
  138.     TIFFMapFileProc mapproc,
  139.     TIFFUnmapFileProc unmapproc
  140. )
  141. #else
  142. TIFFClientOpen(name, mode,
  143.     clientdata, readproc, writeproc, seekproc, closeproc, sizeproc,
  144.     mapproc, unmapproc
  145. )
  146.     const char *name, *mode;
  147.     void *clientdata;
  148.     TIFFReadWriteProc readproc;
  149.     TIFFReadWriteProc writeproc;
  150.     TIFFSeekProc seekproc;
  151.     TIFFCloseProc closeproc;
  152.     TIFFSizeProc sizeproc;
  153.     TIFFMapFileProc mapproc;
  154.     TIFFUnmapFileProc unmapproc;
  155. #endif
  156. {
  157.     static const char module[] = "TIFFClientOpen";
  158.     TIFF *tif;
  159.     int m, bigendian;
  160.  
  161.     m = _TIFFgetMode(mode, module);
  162.     if (m == -1)
  163.         goto bad2;
  164.     tif = (TIFF *)_TIFFmalloc(sizeof (TIFF) + strlen(name) + 1);
  165.     if (tif == NULL) {
  166.         TIFFError(module, "%s: Out of memory (TIFF structure)", name);
  167.         goto bad2;
  168.     }
  169.     memset(tif, 0, sizeof (*tif));
  170.     tif->tif_name = (char *)tif + sizeof (TIFF);
  171.     strcpy(tif->tif_name, name);
  172.     tif->tif_mode = m &~ (O_CREAT|O_TRUNC);
  173.     tif->tif_curdir = -1;        /* non-existent directory */
  174.     tif->tif_curoff = 0;
  175.     tif->tif_curstrip = -1;        /* invalid strip */
  176.     tif->tif_row = -1;        /* read/write pre-increment */
  177.     tif->tif_clientdata = clientdata;
  178.     tif->tif_readproc = readproc;
  179.     tif->tif_writeproc = writeproc;
  180.     tif->tif_seekproc = seekproc;
  181.     tif->tif_closeproc = closeproc;
  182.     tif->tif_sizeproc = sizeproc;
  183.     tif->tif_mapproc = mapproc;
  184.     tif->tif_unmapproc = unmapproc;
  185.  
  186.     { int one = 1; char* cp = (char*)&one; bigendian = (*cp == 0); }
  187.     /*
  188.      * Read in TIFF header.
  189.      */
  190.     if (!ReadOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
  191.         if (tif->tif_mode == O_RDONLY) {
  192.             TIFFError(name, "Cannot read TIFF header");
  193.             goto bad;
  194.         }
  195.         /*
  196.          * Setup header and write.
  197.          */
  198.         tif->tif_header.tiff_magic =  bigendian ?
  199.             TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
  200.         tif->tif_header.tiff_version = TIFF_VERSION;
  201.         tif->tif_header.tiff_diroff = 0;    /* filled in later */
  202.         if (!WriteOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
  203.             TIFFError(name, "Error writing TIFF header");
  204.             goto bad;
  205.         }
  206.         /*
  207.          * Setup the byte order handling.
  208.          */
  209.         TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian);
  210.         /*
  211.          * Setup default directory.
  212.          */
  213.         if (!TIFFDefaultDirectory(tif))
  214.             goto bad;
  215.         tif->tif_diroff = 0;
  216.         return (tif);
  217.     }
  218.     /*
  219.      * Setup the byte order handling.
  220.      */
  221.     if (tif->tif_header.tiff_magic != TIFF_BIGENDIAN &&
  222.         tif->tif_header.tiff_magic != TIFF_LITTLEENDIAN) {
  223.         TIFFError(name,  "Not a TIFF file, bad magic number %d (0x%x)",
  224.             tif->tif_header.tiff_magic,
  225.             tif->tif_header.tiff_magic);
  226.         goto bad;
  227.     }
  228.     TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian);
  229.     /*
  230.      * Swap header if required.
  231.      */
  232.     if (tif->tif_flags & TIFF_SWAB) {
  233.         TIFFSwabShort(&tif->tif_header.tiff_version);
  234.         TIFFSwabLong(&tif->tif_header.tiff_diroff);
  235.     }
  236.     /*
  237.      * Now check version (if needed, it's been byte-swapped).
  238.      * Note that this isn't actually a version number, it's a
  239.      * magic number that doesn't change (stupid).
  240.      */
  241.     if (tif->tif_header.tiff_version != TIFF_VERSION) {
  242.         TIFFError(name,
  243.             "Not a TIFF file, bad version number %d (0x%x)",
  244.             tif->tif_header.tiff_version,
  245.             tif->tif_header.tiff_version); 
  246.         goto bad;
  247.     }
  248.     tif->tif_flags |= TIFF_MYBUFFER;
  249.     tif->tif_rawcp = tif->tif_rawdata = 0;
  250.     tif->tif_rawdatasize = 0;
  251.     /*
  252.      * Setup initial directory.
  253.      */
  254.     switch (mode[0]) {
  255.     case 'r':
  256.         tif->tif_nextdiroff = tif->tif_header.tiff_diroff;
  257.         if (TIFFMapFileContents(tif, &tif->tif_base, &tif->tif_size))
  258.             tif->tif_flags |= TIFF_MAPPED;
  259.         if (TIFFReadDirectory(tif)) {
  260.             tif->tif_rawcc = -1;
  261.             tif->tif_flags |= TIFF_BUFFERSETUP;
  262.             return (tif);
  263.         }
  264.         break;
  265.     case 'a':
  266.         /*
  267.          * Don't append to file that has information
  268.          * byte swapped -- we will write data that is
  269.          * in the opposite order.
  270.          */
  271.         if (tif->tif_flags & TIFF_SWAB) {
  272.             TIFFError(name,
  273.         "Cannot append to file that has opposite byte ordering");
  274.             goto bad;
  275.         }
  276.         /*
  277.          * New directories are automatically append
  278.          * to the end of the directory chain when they
  279.          * are written out (see TIFFWriteDirectory).
  280.          */
  281.         if (!TIFFDefaultDirectory(tif))
  282.             goto bad;
  283.         return (tif);
  284.     }
  285. bad:
  286.     tif->tif_mode = O_RDONLY;    /* XXX avoid flush */
  287.     TIFFClose(tif);
  288.     return ((TIFF *)0);
  289. bad2:
  290.     (void) (*closeproc)(clientdata);
  291.     return ((TIFF *)0);
  292. }
  293.  
  294. u_long
  295. DECLARE1(TIFFScanlineSize, TIFF*, tif)
  296. {
  297.     TIFFDirectory *td = &tif->tif_dir;
  298.     u_long scanline;
  299.     
  300.     scanline = td->td_bitspersample * td->td_imagewidth;
  301.     if (td->td_planarconfig == PLANARCONFIG_CONTIG)
  302.         scanline *= td->td_samplesperpixel;
  303.     return (howmany(scanline, 8));
  304. }
  305.  
  306. /*
  307.  * Query functions to access private data.
  308.  */
  309.  
  310. /*
  311.  * Return open file's name.
  312.  */
  313. const char *
  314. DECLARE1(TIFFFileName, TIFF*, tif)
  315. {
  316.     return (tif->tif_name);
  317. }
  318.  
  319. /*
  320.  * Return open file's I/O descriptor.
  321.  */
  322. int
  323. DECLARE1(TIFFFileno, TIFF*, tif)
  324. {
  325.     return (tif->tif_fd);
  326. }
  327.  
  328. /*
  329.  * Return read/write mode.
  330.  */
  331. int
  332. DECLARE1(TIFFGetMode, TIFF*, tif)
  333. {
  334.     return (tif->tif_mode);
  335. }
  336.  
  337. /*
  338.  * Return nonzero if file is organized in
  339.  * tiles; zero if organized as strips.
  340.  */
  341. int
  342. DECLARE1(TIFFIsTiled, TIFF*, tif)
  343. {
  344.     return (isTiled(tif));
  345. }
  346.  
  347. /*
  348.  * Return current row being read/written.
  349.  */
  350. long
  351. DECLARE1(TIFFCurrentRow, TIFF*, tif)
  352. {
  353.     return (tif->tif_row);
  354. }
  355.  
  356. /*
  357.  * Return index of the current directory.
  358.  */
  359. int
  360. DECLARE1(TIFFCurrentDirectory, TIFF*, tif)
  361. {
  362.     return (tif->tif_curdir);
  363. }
  364.  
  365. /*
  366.  * Return current strip.
  367.  */
  368. int
  369. DECLARE1(TIFFCurrentStrip, TIFF*, tif)
  370. {
  371.     return (tif->tif_curstrip);
  372. }
  373.  
  374. /*
  375.  * Return current tile.
  376.  */
  377. int
  378. DECLARE1(TIFFCurrentTile, TIFF*, tif)
  379. {
  380.     return (tif->tif_curtile);
  381. }
  382.